<template>
	<view class="selectBox" @click.stop="toggleSelect">
		<!-- 遮罩层 -->
		<view v-if="isSelectShow" class="overlay"
			:style="{ opacity: props.opacity, backgroundColor: props.showOverlay ? '#000' : 'transparent' }">
		</view>

		<!-- 默认插槽 -->
		<slot></slot>

		<!-- 列表模式气泡 -->
		<view class="selectItemBox" :class="props.boxPosition === 'bottom' ? 'bottomBox' : 'topBox'"
			v-if="props.type === 'list' && isSelectShow" :style="boxStyle">
			<view class="selectItem" :style="{ alignItems: arrowAlign }">
				<u-icon v-if="props.boxPosition === 'top'" class="icon-jiantou" size="30rpx" name="arrow-down-fill"
					:color="props.bgcRgba" :style="{ margin: arrowMargin }" />

				<view class="selectItemMin"
					:class="{ opcityShadow: props.opacity === '0' || !props.showOverlay, topBoxRow: props.boxPosition === 'top' }"
					:style="{ background: props.bgcRgba }">
					<view class="selectItem-title" v-for="(item, index) in props.selectData" :key="index"
						:class="{ pressed: isPressed === index }" @touchstart="onTouchStart(index)"
						@touchend="onTouchEnd(index)" @click.stop="selectItem(item, index)"
						:style="{ color: props.color }">
						<slot name="itemIcon" :element="item" :index="index">
							<view style="width: fit-content; min-width: 10px;">
								<u-icon v-if="item[props.format.icon]" class="image" :name="item[props.format.icon]"
									size="20" :color="isPressed === index ? '#bfbfbf' : props.color" />
							</view>
						</slot>
						<view>{{ item[props.format.name] }}</view>
					</view>
				</view>

				<u-icon v-if="props.boxPosition === 'bottom'" class="icon-jiantou" size="30rpx" name="arrow-up-fill"
					:color="props.bgcRgba" :style="{ margin: arrowMargin }" />
			</view>
		</view>

		<!-- 气泡模式 -->
		<view class="bubbleItemBox" v-if="props.type === 'bubble' && isSelectShow" :class="bubblePositionClass">
			<u-icon class="icon" name="play-right-fill" :class="iconPositionClass" :color="props.bgcRgba" />
			<view class="bubbleItem-title"
				:style="{ width: props.bubbleWidth + 'rpx', background: props.bgcRgba, color: props.color }"
				@click.stop="emit('bubble', props.bubbleValue)">
				{{ props.bubbleValue }}
			</view>
		</view>
	</view>
</template>

<script setup lang="ts">
	import { ref, computed } from 'vue';

	const emit = defineEmits(['selectFun', 'bubble']);

	const props = defineProps({
		format: {
			type: Object as () => { name : string; icon : string },
			default: () => ({ name: 'name', icon: 'icon' })
		},
		selectData: {
			type: Array as () => any[],
			default: () => []
		},
		position: {
			type: String as () => 'left' | 'center' | 'right' | 'top' | 'bottom',
			default: 'center'
		},
		boxPosition: {
			type: String as () => 'top' | 'bottom',
			default: 'top'
		},
		type: {
			type: String as () => 'list' | 'bubble',
			default: 'list'
		},
		bubbleValue: {
			type: String,
			default: ''
		},
		bubbleWidth: {
			type: Number,
			default: 220
		},
		bgcRgba: {
			type: String,
			default: 'rgba(0, 0, 0, 0.8)'
		},
		color: {
			type: String,
			default: '#fff'
		},
		topOpsotion: {
			type: String as () => 'left' | 'right' | 'center',
			default: 'center'
		},
		showOverlay: {
			type: Boolean,
			default: true
		},
		opacity: {
			type: String,
			default: '0.3'
		}
	});

	const isSelectShow = ref(false);
	const isPressed = ref<number | null>(null);

	const toggleSelect = () => {
		isSelectShow.value = !isSelectShow.value;
	};

	const selectItem = (item : any, index : number) => {
		emit('selectFun', item);
		isSelectShow.value = false;
	};

	const onTouchStart = (index : number) => {
		isPressed.value = index;
	};

	const onTouchEnd = (index : number) => {
		if (isPressed.value === index) isPressed.value = null;
	};

	const arrowAlign = computed(() => {
		if (props.topOpsotion === 'left') return 'flex-start';
		if (props.topOpsotion === 'right') return 'flex-end';
		return 'center';
	});

	const arrowMargin = computed(() => {
		const pos = props.boxPosition;
		const align = props.topOpsotion;
		if (pos === 'top') {
			if (align === 'left') return '0 4px 0 0';
			if (align === 'right') return '0 0 0 4px';
		} else {
			if (align === 'left') return '-4px 0 0 4px';
			if (align === 'right') return '-4px 4px 0 0';
			if (align === 'center') return '-4px 0 0 0';
		}
		return '0';
	});

	const boxStyle = computed(() => {
		return {
			left: props.position === 'center' ? '25%' : props.position === 'left' ? '0' : 'unset',
			right: props.position === 'right' ? '0' : 'unset'
		};
	});

	const bubblePositionClass = computed(() => {
		return props.position;
	});

	const iconPositionClass = computed(() => {
		switch (props.position) {
			case 'top': return 'iconTop';
			case 'bottom': return 'iconBottom';
			case 'left': return 'iconLeft';
			case 'right': return 'iconRight';
			default: return '';
		}
	});
</script>


<style scoped lang="scss">
	/* 气泡选择器 */
	.selectBox {
		width: 100%;
		height: 100%;
		position: relative;

		.overlay {
			z-index: 9999;
			width: 100%;
			height: 100%;
			// background-color: #000;
			position: fixed;
			top: 0;
			left: 0;
		}
	}

	.selectItemBox {
		position: absolute;
		left: 25%;
		z-index: 9999;
		display: flex;
		justify-content: center;
		align-items: center;
	}

	.topBox {
		top: 60%;
	}

	.topBoxRow {
		margin-top: -12rpx;
	}

	.bottomBox {
		bottom: 100%;
	}

	.selectItem {
		display: flex;
		justify-content: center;
		// align-items: center;
		flex-direction: column;
	}

	.selectItem .icon-jiantou {
		// margin-right: 4px;
		font-size: 28rpx;
		font-weight: 400;
		/* color: rgba(0, 0, 0, 0.8); */
		transform: rotate(180deg);
	}

	.selectItemMin {
		padding: 10rpx;
		border-radius: 15rpx;
		max-height: 400rpx;
		/* background: rgba(0, 0, 0, 0.8); */
		overflow-x: hidden;
		overflow-y: scroll;
	}

	.opcityShadow {
		// box-shadow: 0 -10px 14px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
		box-shadow: 0 -4px 26px -19px rgba(0, 0, 0, 0.19), 0 1px 12px -5px rgba(0, 0, 0, 0.23);
	}

	.selectItem-title {
		display: flex;
		align-items: center;
		min-width: 120px;
		// width: fit-content;
		/* height: 50rpx; */
		font-size: 14px;
		/* color: #fff; */
		font-weight: 400;
		padding: 10px 4px;
		// border-bottom: 1rpx solid #d7d7d7;
		transition: color 0.3s ease;

		.image {
			margin-right: 10rpx;
			opacity: 0.8;
		}
	}

	// 手指按下时，修改样式
	.pressed {
		color: #bfbfbf !important;
	}

	.bubbleItemBox {
		position: absolute;
		z-index: 5;
	}

	.bubbleItemBox .icon {
		width: 30rpx;
		height: 30rpx;
		/* color: rgba(0, 0, 0, 0.8); */
		font-size: 50rpx;
		font-weight: 400;
		position: absolute;
		z-index: 5;
	}

	.top {
		left: -100rpx;
		bottom: 130%;
	}

	.iconTop {
		left: 130rpx;
		bottom: -9rpx;
		transform: rotate(90deg);
	}

	.left {
		right: 130%;
		top: 0;
	}

	.iconLeft {
		right: -9rpx;
	}

	.right {
		left: 135%;
		top: 0;
	}

	.iconRight {
		left: -9rpx;
		top: 20rpx;
		transform: rotate(180deg);
	}

	.bottom {
		left: -100rpx;
		top: 130%;
	}

	.iconBottom {
		left: 100rpx;
		top: -9rpx;
		transform: rotate(-90deg);
	}

	.bubbleItem-title {
		/* background: rgba(0, 0, 0, 0.8); */
		padding: 15rpx;
		border-radius: 10rpx;
		width: 220rpx;
		font-size: 28rpx;
		/* color: #fff; */
		line-height: 45rpx;
		display: flex;
		justify-content: center;
		align-items: center;
		flex-wrap: wrap;
	}
</style>